#encoding=utf8
from google.appengine.ext import webapp
from django.utils import simplejson
from common import *
from task import SpikeTask, get_tasks_by_owner

from time import time, sleep
from error import get_error_info

# IT IS NOT XML-RPC, IT JUST SOME HTTP REQUEST AND RESPONSE
class TaskRPC(webapp.RequestHandler):
    postkeyword = {
        'task_id' : unicode,
        'name' : unicode,
        'duetime' : int,
        'remidertime' : int,
        'description': unicode,
        'owner' : unicode,
        'postdatetime' : int
        }
    def __init__(self):
        self.funcdic = {
            ('test') : self.task_test,
            ('create') : self.task_create,
            ('get') : self.task_get,
            ('remove') : self.task_remove,
            ('commit', 'name') : self.task_commit_name,
            ('commit', 'duetime') : self.task_commit_duetime,
            ('commit', 'remidertime') : self.task_commit_remidertime,
            ('commit', 'all') : self.task_commit_all,
            ('set', 'state') : self.task_set_state,
            ('list', 'owner') : self.task_list_owner,
            ('search') : self.task_search,
            ('auth') : self.task_auth
            }
        self.postdict = None
        self.replydict = {'success': False}

    def get(self, action, keyparam=''):
        self.response.out.write('here is an rpctest<br />')
        self.response.out.write('action: %s keyparam: %s' % (action, keyparam))

    def post(self, action, keyparam=''):
        if keyparam == '':
            dkey = (action)
        else:
            dkey = (action, keyparam)
        if self.funcdic.has_key(dkey):
            self._load_postdata()
            self.replydict['actiontype'] = action
            self.replydict['keyparam'] = keyparam
            self.funcdic[dkey]()
        
        self.response.out.write(self._generate_response())

    def _load_postdata(self, ):
        if self.request.POST.has_key('postdata'):
            d = simplejson.loads(self.request.POST['postdata'])
            if d and type(d) == type({}):
                self.postdict = d
        return None

    def _generate_error_info(self, code):
        self.replydict['success'] = False
        err = get_error_info(code)
        self.replydict['error_code'] = err[0]
        self.replydict['debug'] = err[1]

    def task_create(self):
        if not self._task_check(['name', 'duetime', 'remidertime', 'description', 'owner']):
            self._generate_error_info('parse_params_fail_creat')
            return
        try:
            nt = SpikeTask(self.postdict['owner'])
        except Exception, e:
            return
        
        if nt.init_task([self.postdict['name'],
                         self.postdict['duetime'],
                         self.postdict['remidertime']]):
            nt.set_description(self.postdict['description'])
            nt.set_state('normal')
            if not nt.save():
                return
            
            self.replydict['task'] = nt.dump_task()
            self.replydict['success'] = True
    
    def task_get(self):
        if not self._task_check(['task_id']):
            self._generate_error_info('parse_params_fail_get')
            return
        self.replydict['success'] = True
    
    def task_remove(self):
        if not self._task_check(['task_id']):
            self._generate_error_info('parse_params_fail_remove')
            return
        self.replydict['success'] = True
    
    def task_commit_name(self):
        if not self._task_check(['task_id', 'name']):
            self._generate_error_info('parse_params_fail_commit')
            return
        try:
            ct = SpikeTask(task_id=self.postdict['task_id'])
        except Exception, e:
            return
        if not ct or (not ct.change_name(self.postdict['name'])):
            return
        if not ct.save():
            return
        
        self.replydict['task'] = ct.dump_task()
        self.replydict['success'] = True
    
    def task_commit_duetime(self):
        if not self._task_check(['task_id', 'duetime']):
            self._generate_error_info('parse_params_fail_commit')
            return

        debug_output(self.postdict['duetime']);
        import time
        debug_output(time.localtime(int(self.postdict['duetime'])));

        try:
            ct = SpikeTask(task_id=self.postdict['task_id'])
        except Exception, e:
            return
        if not ct or (not ct.change_duetime(self.postdict['duetime'])):
            return
        if not ct.save():
            return
        
        self.replydict['task'] = ct.dump_task()
        self.replydict['success'] = True
    
    def task_commit_remidertime(self):
        if not self._task_check(['task_id', 'remidertime']):
            self._generate_error_info('parse_params_fail_commit')
            return
        self.replydict['success'] = True

    def task_commit_all(self):
        if not self._task_check(['task_id', 'name', 'duetime', 'remidertime']):
            self._generate_error_info('parse_params_fail_commit')
            return
        self.replydict['success'] = True

    def task_set_state(self):
        if not self._task_check(['task_id', 'state']):
            self._generate_error_info('change_status_fail')
            return
        
        try:
            tobj = SpikeTask(task_id=self.postdict['task_id'])
        except Exception, e:
            return
        if not tobj or (not tobj.set_state(self.postdict['state'])):
            return
        if not tobj.save():
            return
        
        self.replydict['task'] = tobj.dump_task()
        self.replydict['success'] = True
    
    def task_list_owner(self):
        if not self._task_check(['owner']):
            self._generate_error_info('parse_params_fail_list')
            return
        # get all task specify by user name
        tasklist = get_tasks_by_owner(self.postdict['owner'])
        obj = []
        if tasklist:
            for task in tasklist:
                obj.append(self._dump_task(task.task_id))
        self.replydict['task_list'] = obj
        self.replydict['success'] = True
        self.replydict['owner'] = self.postdict['owner']
    
    def task_search(self):
        if not self._task_check(['search_keyword']):
            self._generate_error_info('parse_params_fail_search')
            return
        self.replydict['success'] = True
    
    def task_auth(self):
        if not self._task_check(['owner']):
            self._generate_error_info('parse_params_fail_auth')
            return
        self.replydict['success'] = True

    def task_test(self):
        self.replydict['success'] = True
        self.replydict['debug'] = 'post test rpc success'

    # convert task to simple datasture (for json)
    def _dump_task(self, dump_task_id):
        return SpikeTask(task_id=dump_task_id).dump_task()

    def _task_check(self, plist):
        "check for request data for a request"
        if not plist or type(plist) != list:
            return False
        if not self.postdict or type(self.postdict) != dict:
            return False
        for param in plist:
            if TaskRPC.postkeyword.has_key(param):
                if not self.postdict.has_key(param):
                    return False
                if type(self.postdict[param]) != TaskRPC.postkeyword[param]:
                    return False
        return True

    def _generate_response(self):
        return simplejson.dumps(self.replydict)
